/************************************************************************************
 RC Hobby Stream
 Twitter automatic feeder

 First version developed with support of Mapelgate Media

"RC Hobby Stream" is protected by the copyright law
© 2011 Enrico Miglino / Tech Consulting (enrico.miglino@ovi.com)
Distributed under the LGPL 3.0 license.

This file is part of "RC Hobby Stream".

    "RC Hobby Stream" is free software: you can redistribute it
    and/or modify it under the terms of the Lesser GNU General Public License
    as published by the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    "RC Hobby Stream" is distributed in the hope that it
    will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    Lesser GNU General Public License for more details.

    You should have received a copy of the Lesser GNU General Public License
    along with "RC Hobby Stream".
    If not, see <http://www.gnu.org/licenses/>.
************************************************************************************/

import Qt 4.7
import "elements" 1.0 as Smith  // Components folder

Item {
    id: screen  // This is the main screen block

    // Screen size
    property int horizontalDimension: 188
    property int verticalDimension: 370
    // rss refresh progress bar left + right margins
    // Used to calculate exactly the real width (= horizontalDimension - refreshBarMargins)
    property int refreshBarMargins: 20

    width: horizontalDimension; height: verticalDimension
    // TODO: set the screen dimension (with background image adaption) parametric

    property bool userView : false
    property int waitDuration: 3000     // Default delay to show splash screen
    property int helpDuration: 5000     // Default help message duration.
    property int bannerDuration: 10000   // Default AD banner viewing for rotation

    // Delay for Feed updates.
    // Every timer period (waitFeed duration), the progress bar is incremented
    // in width from 2 to its max real width. The number of steps is defined in
    // waitRefresh. When the maximum lenght of the bar is reached, the refresh function
    // is called in rssModel and the bar lenght is reset to 2
    property int waitFeed: 10000    // 10 sec (progress bar update)
    property int waitRefresh: 6    // * 10 sec (feed update)
    property int waitFeedCounter: 0 // waitFeed cycle counter

    // z-values used to correctly set views and toolbars
    property int zTop: 4    // Topmost z-value (used to show app buttons toolbars)
    property int zMask: 2   // Layout graphic mask z-value
    property int zQuit: 3   // Quit button z-value
    property int zToolbar: 3    // Button toolbar z-value
    property int zBottom: -1    // z-value to hide and object under the main background
    property int zTwitter: 1    // z-value for the Twitter feed (shown under the mask)
    property int zHelp: 5       // z-value for help online.

    /*****************************************************************************
        Toolbar buttons management properties
    ****************************************************************************/

    property bool statusBlog: false     // Initial status for the button toolbars
    property bool statusMail: false
    property bool statusVideo: false
    property bool statusWeb: false
    property bool statusSetup: false
    property bool statusHowTo: false

    // ---------------------------------------------------------- APP PARAMETERS
    // Toolbar for setup button
    property string optionTitle: "Setup"
    property string optiontxt1: "Fly RC mag"
    property string optiontxt2: "Rc Driver Guys"
    property string optiontxt3: "Robot Magazine"
    property string optiontxt4: "RC Group Buy"
    property string optiontxt5: "RC Helipilot"

    // All flag for the feeds to select are initially set to true
    property bool flag1Set: true
    property bool flag2Set: true
    property bool flag3Set: true
    property bool flag4Set: true
    property bool flag5Set: true

    // The 'from:' search keywords for the relative flags
    property string key1from: "Flyrcmag"
    property string key2from: "Rcdriverguys"
    property string key3from: "Robot_magazine"
    property string key4from: "Rcgroupbuy"
    property string key5from: "rchelipilot"

    // Toolbar for blog button
    property string blogTitle: "Our Blogs"
    property string blogtxt1: "Fly RC mag"
    property string blogtxt2: "Rc Driver Guys"
    property string blogtxt3: "Robot Magazine"
    property string blogtxt4: "RC Group Buy"
    property string blogtxt5: "RC Helipilot"

    // Toolbar for mail button
    property string mailTitle: "Send Mail To"
    property string mailtxt1: "Fly RC mag"
    property string mailtxt2: "Rc Driver Guys"
    property string mailtxt3: "Robot Magazine"
    property string mailtxt4: "RC Group Buy"
    property string mailtxt5: "RC Helipilot"

    // Toolbar for video button
    property string videoTitle: "Our Video"
    property string videotxt1: "Fly RC mag"
    property string videotxt2: "Rc Driver Guys"
    property string videotxt3: "Robot Magazine"
    property string videotxt4: "RC Group Buy"
    property string videotxt5: "RC Helipilot"

    // Toolbar for web button
    property string webTitle: "Web Links"
    property string webtxt1: "Fly RC mag"
    property string webtxt2: "Rc Driver Guys"
    property string webtxt3: "Robot Magazine"
    property string webtxt4: "RC Group Buy"
    property string webtxt5: "RC Helipilot"

    // Toolbar for how-to button
    property string howtoTitle: "How-To Links"
    property string howtotxt1: "Fly RC mag"
    property string howtotxt2: "Rc Driver Guys"
    property string howtotxt3: "Robot Magazine"
    property string howtotxt4: "RC Group Buy"
    property string howtotxt5: "RC Helipilot"

    // ---------------------------------------------------------- START DEBUG BLOCK
    // Debug info.
    // For debug console messages use debugMessage(msg) instead of console.log(msg)
    // in the source module set baseMsg property with the string that should appear
    // before any debug message on the console.
    // To disable debug, set debugStatus to false. This can be done also only in some
    // code blocks.
    property bool debugStatus: false
    property string baseMsg: "*** Debug main: "
    function debugMessage(msg) { if (debugStatus == true) console.log(baseMsg + msg); }
    // ---------------------------------------------------------- END DEBUG BLOCK

    /*  processButtons(btnNum)

        Manage the toolbar buttons events. The events associated to the buttons occours
        only if the power button has pressed (state ON)
    */
    function processButtons(btnNum) {
        // Buttons have effect only if the splash screen has finished its animation
        if (splashimage.splashHide == true) {
            // Change the status of the respective toolbar.
            // All other toolbars are hidden, so only the last selected
            // toolbar is shown. If the same button is pressed twice, also
            // the currently shown toolbar hides.
            switch (btnNum) {
            case 1: // Blog
                if (statusBlog == false) {
                    // hide all the other toolbars
                    toolbarHowTo.z = zBottom; toolbarMail.z = zBottom; toolbarSetup.z = zBottom;
                    toolbarVideo.z = zBottom; toolbarWeb.z = zBottom; statusHowTo = false;
                    statusMail = false; statusSetup = false; statusVideo = false; statusWeb = false;
                    // show the toolbar
                    toolbarBlog.z = zTop;
                    helpDisplay(1);
                }
                else {
                    toolbarBlog.z = zBottom;
                }
                statusBlog = !statusBlog;
                break;
            case 2: // Mail
                if (statusMail == false) {
                    // hide all the other toolbars
                    toolbarHowTo.z = zBottom; toolbarSetup.z = zBottom; toolbarVideo.z = zBottom;
                    toolbarWeb.z = zBottom; toolbarBlog.z = zBottom; statusBlog = false;
                    statusHowTo = false; statusSetup = false; statusVideo = false; statusWeb = false;
                    // show the toolbar
                    toolbarMail.z = zTop;
                    helpDisplay(2);
                }
                else {
                    toolbarMail.z = zBottom;
                }
                statusMail = !statusMail;
                break;
            case 3: // Video
                if (statusVideo == false) {
                    // hide all the other toolbars
                    toolbarHowTo.z = zBottom; toolbarMail.z = zBottom; toolbarSetup.z = zBottom;
                    toolbarWeb.z = zBottom; toolbarBlog.z = zBottom; statusBlog = false;
                    statusHowTo = false; statusMail = false; statusSetup = false; statusWeb = false;
                    // show the toolbar
                    toolbarVideo.z = zTop;
                    helpDisplay(3);
            }
            else {
                toolbarVideo.z = zBottom;
            }
            statusVideo = !statusVideo;
                break;
            case 4: // Web
                if (statusWeb == false) {
                    // hide all the other toolbars
                    toolbarHowTo.z = zBottom; toolbarMail.z = zBottom; toolbarSetup.z = zBottom;
                    toolbarVideo.z = zBottom; toolbarBlog.z = zBottom; statusBlog = false; statusHowTo = false;
                    statusMail = false; statusSetup = false; statusVideo = false;
                    // show the toolbar
                    toolbarWeb.z = zTop;
                    helpDisplay(4);
            }
            else {
                toolbarWeb.z = zBottom;
            }
            statusWeb = !statusWeb;
                break;
            case 5: // Setup
                    // Change the status of the toolbar.
                    if (statusSetup == false) {
                    // hide all the other toolbars
                    toolbarHowTo.z = zBottom; toolbarMail.z = zBottom; toolbarVideo.z = zBottom;
                    toolbarWeb.z = zBottom; toolbarBlog.z = zBottom; statusBlog = false;
                    statusHowTo = false; statusMail = false; statusVideo = false; statusWeb = false;
                    // Set the current flag status to the buttons
                    setupFlags();
                    // show the toolbar
                    toolbarSetup.z = zTop;
                    helpDisplay(5);
                }
                else {
                    // Check if the user pressed a button to change its state
                    if (toolbarSetup.button1Changed ||
                        toolbarSetup.button2Changed ||
                        toolbarSetup.button3Changed ||
                        toolbarSetup.button4Changed ||
                        toolbarSetup.button5Changed) {
                        debugMessage("at least one setup button has changed")
                        // Save the state of all flags
                        flag1Set = toolbarSetup.button1Flag;
                        flag2Set = toolbarSetup.button2Flag;
                        flag3Set = toolbarSetup.button3Flag;
                        flag4Set = toolbarSetup.button4Flag;
                        flag5Set = toolbarSetup.button5Flag;
                        // Check if at least one flag was left on
                        // else force the first flag to be set.
                        if ((flag1Set + flag2Set + flag3Set + flag4Set + flag5Set) == 0) {
                            debugMessage("No one flag is set: force flag1Set = true")
                            // Warning: at least one flag should be set to true during all the
                            // program cycle.
                            flag1Set = true;
                        }
                        // Set the current flag status to the buttons
                        setupFlags();
                        // reload rssFeed to update search.
                        rssModel.reload;
                    }
                    // Hide flag toolbar
                    toolbarSetup.z = zBottom;
                }
                statusSetup = !statusSetup;
                break;
            case 6: // How-To
                // Change the status of the toolbar.
                if (statusHowTo == false) {
                    // hide all the other toolbars
                    toolbarMail.z = zBottom; toolbarSetup.z = zBottom; toolbarVideo.z = zBottom;
                    toolbarWeb.z = zBottom; toolbarBlog.z = zBottom; statusBlog = false;
                    statusMail = false; statusSetup = false; statusVideo = false; statusWeb = false;
                    // show the toolbar
                    toolbarHowTo.z = zTop;
                    helpDisplay(6);
                }
                else {
                    toolbarHowTo.z = zBottom;
                }
                statusHowTo = !statusHowTo;
                break;
            }
        }
    }

    /*  setupFlags()

        Initialize setup flags to the current value, before showing the setup toolbar
    */
    function setupFlags() {
        // Get current setup flag configuration
        toolbarSetup.button1Flag = flag1Set;
        toolbarSetup.button2Flag = flag2Set;
        toolbarSetup.button3Flag = flag3Set;
        toolbarSetup.button4Flag = flag4Set;
        toolbarSetup.button5Flag = flag5Set;
        // Reset flag changed before to show the toolbar
        toolbarSetup.button1Changed = false;
        toolbarSetup.button2Changed = false;
        toolbarSetup.button3Changed = false;
        toolbarSetup.button4Changed = false;
        toolbarSetup.button5Changed = false;
    }

    /*  Functions to process link toolbars

        Every toolbar responds to a function that launch a preset link
        or start a mailto: url
    */

    // Video links toolbar
    function processVideo(btnNum) {
        switch(btnNum) {
        case 1: // Fly RC mag
                Qt.openUrlExternally("http://find.flyrc.com/videos");
                break;
        case 2: // Rc Driver Guys
                Qt.openUrlExternally("http://find.rcdriver.com/videos");
                break;
        case 3: // Robot Magazine
                Qt.openUrlExternally("http://find.botmag.com/videos");
                break;
//        case 4: // RC Group Buy
//                Qt.openUrlExternally("mailto:app@rcgroupbuy.com");
//                break;
        case 5: // RC Helipilot
                Qt.openUrlExternally("http://find.helipilotonline.com/videos");
                break;
        }
    }

    // Mail link toolbar
    function processMail(btnNum) {
        switch(btnNum) {
        case 1: // Fly RC mag
                Qt.openUrlExternally("mailto:app@flyrc.com");
                break;
        case 2: // Rc Driver Guys
                Qt.openUrlExternally("mailto:app@rcdriver.com");
                break;
        case 3: // Robot Magazine
                Qt.openUrlExternally("mailto:app@botmag.com");
                break;
        case 4: // RC Group Buy
                Qt.openUrlExternally("mailto:app@rcgroupbuy.com");
                break;
        case 5: // RC Helipilot
                Qt.openUrlExternally("mailto:app@helipilotonline.com");
                break;
        }
    }

    // How-To toolbar
    function processHowTo(btnNum) {
        switch(btnNum) {
        case 1: // Fly RC mag
                Qt.openUrlExternally("http://find.flyrc.com/howto_search");
                break;
        case 2: // Rc Driver Guys
                Qt.openUrlExternally("http://find.rcdriver.com/howto_search");
                break;
        case 3: // Robot Magazine
                Qt.openUrlExternally("http://find.botmag.com/How_To");
                break;
//        case 4: // RC Group Buy
//                Qt.openUrlExternally("mailto:app@rcgroupbuy.com");
//                break;
        case 5: // RC Helipilot
                Qt.openUrlExternally("http://find.helipilotonline.com/howto_search");
                break;
        }
    }

    // Blog toolbar
    function processBlog(btnNum) {
        switch(btnNum) {
        case 1: // Fly RC mag
                Qt.openUrlExternally("http://www.flyrc.com/blog");
                break;
        case 2: // Rc Driver Guys
                Qt.openUrlExternally("http://www.rcdriver.com/blog");
                break;
        case 3: // Robot Magazine
                Qt.openUrlExternally("http://www.botmag.com/blog");
                break;
        case 4: // RC Group Buy
                Qt.openUrlExternally("http://www.rcgroupbuy.com/blog");
                break;
        case 5: // RC Helipilot
                Qt.openUrlExternally("http://www.helipilotonline.com/blog");
                break;
        }
    }

    // Web link toolbar
    function processWeb(btnNum) {
        switch(btnNum) {
        case 1: // Fly RC mag
                Qt.openUrlExternally("http://www.flyrc.com");
                break;
        case 2: // Rc Driver Guys
                Qt.openUrlExternally("http://www.rcdriver.com");
                break;
        case 3: // Robot Magazine
                Qt.openUrlExternally("http://www.botmag.com");
                break;
        case 4: // RC Group Buy
                Qt.openUrlExternally("http://www.rcgroupbuy.com");
                break;
        case 5: // RC Helipilot
                Qt.openUrlExternally("http://www.helipilotonline.com");
                break;
        }
    }

    // Timer used to wait showing the splash screen. When timer stops, trigger change
    // the state of splash shown flags so the image is removed from the screen.
    // Note: if running is set to false, timer should be activated by an external event
    //       i.e. the power button.
    Timer {
        id: waitCycle
        interval: waitDuration; running: true; repeat: false
        onTriggered: {
            splashimage.splashShown = false
            splashimage.splashHide = true
            mainView.z = zTwitter
            toolBar.z = zToolbar
            waitTwitter.running = true
            helpDisplay(0)
        }
    }

    /*  updateKeyword()

        Update the feed changing the 'from:' query keyword to the next active
        flag.
    */

    function updateKeyword() {
        // Load the current flag status
        var flagStatus = [flag1Set, flag2Set, flag3Set, flag4Set, flag5Set ];
        // Query concatenation string. This is the init of the queue string,
        // then this value changes with " OR "  for the next flags (if any)
        var queryConcatString = "q=";
        // Empty the previous 'from' query string
        rssModel.from = ""
        // Loop to check all the flag status
        for (var i=0; i < 5; i++)
            {
            // If the current flag is set, then add the search term to the query string.
            if (flagStatus[i] == true) {
                if (queryConcatString == "q=") {
                    // Init of the query string
                    rssModel.from = queryConcatString;
                    // Add query string
                    createQueryString(i + 1);
                    // Set concatenation string for next flags (if any)
                    queryConcatString = " OR ";
                }
                else {
                    // Add next concatenation string
                    rssModel.from = rssModel.from + queryConcatString;
                    // Add query string
                    createQueryString(i + 1);
                }
            }
        }
        debugMessage("Created query string: " + rssModel.from);
    }

    /*  createQueryString(flagNum)

        Based on the active flags, create the query string used for the next
        twitter update.
    */

    function createQueryString(flagNum) {
        // Append the "from:xxx" user to the query
        switch(flagNum) {
        case 1:
                rssModel.from = rssModel.from + "from:Flyrcmag";
                break;
        case 2:
                rssModel.from = rssModel.from + "from:Rcdriverguys";
                break;
        case 3:
                rssModel.from = rssModel.from + "from:Robot_magazine";
                break;
        case 4:
                rssModel.from = rssModel.from + "from:Rcgroupbuy";
                break;
        case 5:
                rssModel.from = rssModel.from + "from:rchelipilot";
                break;
        }
        debugMessage("rssModel from: set to " + rssModel.from);

    }


    // Timer used to periodically update the feed.
    Timer {
        id: waitTwitter
        interval: waitFeed; running: false; repeat: true
        onTriggered: {
            waitFeedCounter = waitFeedCounter + 1   // Increment the counter
            if (waitFeedCounter > waitRefresh) {
                debugMessage("rssModel refresh")
                waitFeedCounter = 1 // Reset counter
                updateKeyword();     // Update query keyword
                rssModel.reload;     // Update Twitter rss feed
                refreshProgressBar.width = 2    // Reset progress bar lenght
                helpDisplay(100);
            }
            else {
                refreshProgressBar.width = (horizontalDimension - refreshBarMargins) / waitRefresh * waitFeedCounter
            }
           debugMessage("Wait step")
        }
    }

    // This white rectangle is layered to the base background of the app.
    // All the button toolbars are build and setup, then are hidden with a z=-1
    // setting. When one of the main app buttons are pressed, the corresponding
    // toolbar is shown rising it changing its z attribute to a value higher than
    // al the other views.
    Rectangle {
        id: background  // background rectangle

        width: horizontalDimension - 16; height: verticalDimension - 80
        anchors.horizontalCenter: screen.horizontalCenter
        anchors.verticalCenter: screen.verticalCenter
        color: "#ffffff";
    }

    Rectangle {
        id: refreshProgressBar  // progress bar to show time remaining before next rssModel reload

        width: 2; height: 6
        x: 10; y: 61; z: zToolbar

        gradient: Gradient {
            GradientStop { position: 0.0; color: "#00ff34" }
            GradientStop { position: 0.1; color: "#00a6ff" }
        }
    }

    // --------------------------------------------- MAIN APP TOOLBAR
    Smith.ToolBar {
        id: toolBar // Toolbar object definition

        anchors.top: parent.top;
        z: zBottom // Toolbar is set hidden. Will be shown after splash screen.
        // Move the toolbar to the absolute position relative to the background image
        // Without a background, this position can be freely decided.
        // All the buttons are childs of the toolbar so they are automatically positioned
        // in the right place.
        // Note: The best way for relative button position is to use a set of
        // layout grids.
        transform: Translate { x: 16; y: 293 }
        // Buttons event callback function
        onButton1Clicked: processButtons(1)
        onButton2Clicked: processButtons(2)
        onButton3Clicked: processButtons(3)
        onButton4Clicked: processButtons(4)
        onButton5Clicked: processButtons(5)
        onButton6Clicked: processButtons(6)
    }

    // -------------------------------------------------------------------
    // Splash screen, shown at the program startup. See notes if needs to
    // cange the visualization default.
    // -------------------------------------------------------------------
    Smith.Splash {
        id: splashimage // Splash image shown when program is in power-off state
        property bool splashShown: true // Set to true to appear automatically. If set to false, appear only
                                        // when the bool status changes (see behaviors below)
        property bool splashHide: false
        // Move the image to the right position and hide.
        // Note: if the opacity value is set-up only in the image definition,
        // then it seems impossible to change this value in the animation, so it is
        // set here.
        transform: Translate { x: 9; y: 72 }
        opacity: 1  // If splash screen is 0 by default it is not shown at startup
        // In / out fading animations beaviored to the status flags
        Behavior on splashShown {
                NumberAnimation { target: splashimage; property: "opacity"; to: 1; duration: 500 }
            }
        Behavior on splashHide {
                NumberAnimation { target: splashimage; property: "opacity"; to: 0; duration: 500 }
            }
    }

    // --------------------------------------------- TWITTER FEED
    // Components and objects for the twitter feed on the screen
    // -------------------------------------------------------------------

    // xml data model
    Smith.TweetRssModel {
        id: rssModel
    }

    // Rotating image shown while list components are lodaing from the web
    Smith.Wait {
        anchors.centerIn: parent;
        visible: rssModel.status == XmlListModel.Loading && state!='unauthed'
    }

    // The view item to manage the message list
    Item {
        id: twitterView // Define the view for the feed list

        anchors.left: screen.left; anchors.top: screen.top
//        anchors.topMargin: 100

        // Mask image is a png with the transparent area to show the message
        // list. The z property is set to 1: immediately above the screen background
        Image {
            id: mask

            fillMode: Image.PreserveAspectFit
            smooth: true; z: zMask
            source: "images/SmithMask.png"
        }

        x: 2; y:10
        width: parent.width - 8
        height: screen.horizontalDimension
        // TODO: Check for alternate position respect the screen background

        // This component defines the layout and data model for every message
        Smith.TweetComponent {
            id: fatDelegate // Define the component model for the message list
        }

        ListView {
            id: mainView;   // Definition of the list view based on the fatDelegate layout

            model: rssModel.model;  // Data model
            delegate: fatDelegate   // Representation template
            width: parent.width - 6;
            height: parent.height; y: 70; x: 2; z: zBottom
            cacheBuffer: 200;
        }
    }

    // --------------------------------------------- BUTTONS TOOLBARS
    // Setting of the six different toolbars raised when the corresponding
    // button in the bottom toolbar is pressed.
    // -------------------------------------------------------------------

    Smith.ToolBarSetup {
        id: toolbarSetup    // Definition of the toolbar with search setup options

        // Toolbar position on top of the main user screen, taking regard of the
        // graphic image of the mask
        anchors.verticalCenter: screen.verticalCenter
        anchors.horizontalCenter: screen.horizontalCenter
        anchors.verticalCenterOffset: -5
        z: zBottom   // Initially the toolbar is set under the app main background

        // Set option buttons texts
        button1Label: optiontxt1
        button2Label: optiontxt2
        button3Label: optiontxt3
        button4Label: optiontxt4
        button5Label: optiontxt5
        title: optionTitle
    }

    Smith.ToolBarBlog {
        id: toolbarBlog    // Definition of the toolbar

        // Toolbar position on top of the main user screen, taking regard of the
        // graphic image of the mask
        anchors.verticalCenter: screen.verticalCenter
        anchors.horizontalCenter: screen.horizontalCenter
        anchors.verticalCenterOffset: -5
        z: zBottom   // Initially the toolbar is set under the app main background

        // Set option buttons texts
        link1Label: blogtxt1
        link2Label: blogtxt2
        link3Label: blogtxt3
        link4Label: blogtxt4
        link5Label: blogtxt5
        title: blogTitle
        // Buttons event callback function
        onButton1Clicked: processBlog(1)
        onButton2Clicked: processBlog(2)
        onButton3Clicked: processBlog(3)
        onButton4Clicked: processBlog(4)
        onButton5Clicked: processBlog(5)
    }

    Smith.ToolBarHowto {
        id: toolbarHowTo    // Definition of the toolbar

        // Toolbar position on top of the main user screen, taking regard of the
        // graphic image of the mask
        anchors.verticalCenter: screen.verticalCenter
        anchors.horizontalCenter: screen.horizontalCenter
        anchors.verticalCenterOffset: -5
        z: zBottom   // Initially the toolbar is set under the app main background

        // Set option buttons texts
        link1Label: howtotxt1
        link2Label: howtotxt2
        link3Label: howtotxt3
//        link4Label: howtotxt4
        link5Label: howtotxt5
        title: howtoTitle
        // Buttons event callback function
        onButton1Clicked: processHowTo(1)
        onButton2Clicked: processHowTo(2)
        onButton3Clicked: processHowTo(3)
//        onButton4Clicked: processHowTo(4)
        onButton5Clicked: processHowTo(5)
    }

    Smith.ToolBarMail {
        id: toolbarMail    // Definition of the toolbar

        // Toolbar position on top of the main user screen, taking regard of the
        // graphic image of the mask
        anchors.verticalCenter: screen.verticalCenter
        anchors.horizontalCenter: screen.horizontalCenter
        anchors.verticalCenterOffset: -5
        z: zBottom   // Initially the toolbar is set under the app main background

        // Set option buttons texts
        link1Label: mailtxt1
        link2Label: mailtxt2
        link3Label: mailtxt3
        link4Label: mailtxt4
        link5Label: mailtxt5
        title: mailTitle
        // Buttons event callback function
        onButton1Clicked: processMail(1)
        onButton2Clicked: processMail(2)
        onButton3Clicked: processMail(3)
        onButton4Clicked: processMail(4)
        onButton5Clicked: processMail(5)
    }

    Smith.ToolBarWeb {
        id: toolbarWeb    // Definition of the toolbar

        // Toolbar position on top of the main user screen, taking regard of the
        // graphic image of the mask
        anchors.verticalCenter: screen.verticalCenter
        anchors.horizontalCenter: screen.horizontalCenter
        anchors.verticalCenterOffset: -5
        z: zBottom   // Initially the toolbar is set under the app main background

        // Set option buttons texts
        link1Label: webtxt1
        link2Label: webtxt2
        link3Label: webtxt3
        link4Label: webtxt4
        link5Label: webtxt5
        title: webTitle
        // Buttons event callback function
        onButton1Clicked: processWeb(1)
        onButton2Clicked: processWeb(2)
        onButton3Clicked: processWeb(3)
        onButton4Clicked: processWeb(4)
        onButton5Clicked: processWeb(5)
    }

    Smith.ToolBarVideo {
        id: toolbarVideo    // Definition of the toolbar

        // Toolbar position on top of the main user screen, taking regard of the
        // graphic image of the mask
        anchors.verticalCenter: screen.verticalCenter
        anchors.horizontalCenter: screen.horizontalCenter
        anchors.verticalCenterOffset: -5
        z: zBottom   // Initially the toolbar is set under the app main background

        // Set option buttons texts
        link1Label: videotxt1
        link2Label: videotxt2
        link3Label: videotxt3
//        link4Label: videotxt4
        link5Label: videotxt5
        title: videoTitle
        // Buttons event callback function
        onButton1Clicked: processVideo(1)
        onButton2Clicked: processVideo(2)
        onButton3Clicked: processVideo(3)
//        onButton4Clicked: processVideo(4)
        onButton5Clicked: processVideo(5)
    }

    // --------------------------------------------- CONTEXTUAL HELP
    // Management for the contextual help showing actions the user can
    // do in the various app conditions.
    // -------------------------------------------------------------------

    /*  helpDisplay(helpCode)

        Display the corresponding 'helpCode' text in the help area
        showing it.
    */

    function helpDisplay(helpCode) {
        // Check if help is already showing something
        if (helpText.helpActive == true) {
            // suspend timer and help showing
            helpText.helpActive = false;
            waitHelp.running = false;
        }

        // Show help area with the required text
        helpText.opacity = 1;
        switch(helpCode) {
        case 0:
                helpText.message = "Press the buttons for more options. Press twice to show the main screen.";
            break;
        case 1:
                helpText.message = "Press a button to show one of the desired blog in your browser.";
            break;
        case 2:
                helpText.message = "Press a button to contact by mail one of our magazine.";
            break;
        case 3:
                helpText.message = "Press a button to show the last recent video articles.";
            break;
        case 4:
                helpText.message = "Press a button to show the magazine web page in your browser.";
            break;
        case 5:
                helpText.message = "Press a button to select/deselect the desired feeds.";
            break;
        case 6:
                helpText.message = "Press a button to view the last published how-to in your browser.";
            break;
        case 100:
                helpText.message = "Wait few seconds. Updating the selected feeds.";
            break;
        default:
                helpText.message = "No Help available";
            break;
        }
        helpText.helpActive = true; // trigger the timer to show help
        waitHelp.running = true;
    }

    /*  helpDebug(helpString)

        Display the 'helpString' text in the help area. This function is for debug
        purposes at runtime. It works only if the debug flag is true.
        Due to the behaviour of the timer trigger the debug messages are shown for 5
        seconds then disappear.
        This function has low priority respect the normal contextuaql help calls that
        executes without take care if a debug message is shown.
        Otherwise, if a debug message, it shows anyway also if a contextual help is showing.
    */

    function helpDebug(helpString) {
        // Check if debug flag is set
        if (debugStatus == true) {
            if (helpText.helpActive == true) {
                // suspend timer and help showing
                helpText.helpActive = false;
                waitHelp.running = false;
            }
            // Show help area and set the debug message
            helpText.message = helpString;
            helpText.opacity = 1;
            helpText.helpActive = true; // trigger the timer to show help
            waitHelp.running = true;
        }
    }

    // Help display area definition
    Smith.Help {
        id: helpText

        // Flag to trigger the wait cycle showing help
        property bool helpActive: false
        opacity: 0  // help area is activated only when is needed.
        z: zHelp
    }

    // Timer used to wait showing the help messages.
    Timer {
        id: waitHelp

        interval: helpDuration; running: false; repeat: false
        onTriggered: {
            helpText.helpActive = false; helpText.opacity = 0;
        }
    }

    // --------------------------------------------- BANNERS
    // Ad banner web object that should be shown rotating every 5 seconds
    // on top of the screen
    // -------------------------------------------------------------------

    // It is not clear why the banner to appear in the right position on the screen
    // should be moved outside. It seems that its axis origin are in another place
    // than where we think they should be.
    property int bannerX: -68
    property int bannerY: 1

    Smith.Ad_heli {
        id: bannerHeli
        opacity: 0; x: bannerX; y: bannerY
        adLinkedUrl: "http://webads.morerc.com/www/delivery/ck.php?zoneid=47"
    }

    Smith.Adfly_rc {
        id: bannerFlyrc
        opacity: 1; x: bannerX; y: bannerY
        adLinkedUrl: "http://webads.morerc.com/www/delivery/ck.php?zoneid=45"
     }

    Smith.Adrc_driver {
        id: bannerRcdriver
        opacity: 0; x: bannerX; y: bannerY
        adLinkedUrl: "http://webads.morerc.com/www/delivery/ck.php?zoneid=46"
    }

    Smith.Adrc_groupbuy {
        id: bannerRcgroupbuy
        opacity: 0; x: bannerX; y: bannerY
        adLinkedUrl: "http://webads.morerc.com/www/delivery/ck.php?zoneid=48"
    }

    Smith.Adrobot_magazine {
        id: bannerRobot
        opacity: 0; x: bannerX; y: bannerY
        adLinkedUrl: "http://webads.morerc.com/www/delivery/ck.php?zoneid=44"
    }

    // Rotation banner timer variables
    property int rotatorCounter: 1
    property int numberBanners: 5

    /*  showBanner(flag)

        Show or hide the current banner.
    */
    function showBanner(flag) {
        switch (rotatorCounter) {
        case 1:
            bannerFlyrc.opacity = 1 * flag;
            break;
        case 2:
            bannerRcdriver.opacity = 1 * flag;
            break;
        case 3:
            bannerRobot.opacity = 1 * flag;
            break;
        case 4:
            bannerRcgroupbuy.opacity = 1 * flag;
            break;
        case 5:
            bannerHeli.opacity = 1 * flag;
            break;
        }
    }

    /*  rotateAD_Banner(bannerNum)

        Set the position counter to the next banner to be shown
        If a flag is not set, user decided to exclude the corresponding
        feed from the list, so the corresponding ad banner is not shown.
        The next banner to be shown can be the same, is only one feed is
        selected.
    */
    function rotateAD_Banner() {
        // Load the current flag status in a vector
        var flagStatus = [flag1Set, flag2Set, flag3Set, flag4Set, flag5Set ];

        // Set to the next banner position
        rotatorCounter = rotatorCounter + 1;
        // The value should remain in the range
        if (rotatorCounter > numberBanners)
            rotatorCounter = 1;

        // Search for the first valid banner number to be shown
        while (flagStatus[rotatorCounter - 1] != true) {
            rotatorCounter = rotatorCounter + 1;
            // If counter reach the end is reset
            if (rotatorCounter > numberBanners)
                rotatorCounter = 1;
        }
    }

    // Timer used to periodically update the feed.
    Timer {
        id: bannerRotation
        interval: bannerDuration; running: true; repeat: true
        onTriggered: {
            // Hide the current banner
            showBanner(false);
            // set the new banner pointer
            rotateAD_Banner();
            // Show the new banner
            showBanner(true);
            debugMessage("Rotate banner..." + rotatorCounter);
        }
    }

    // Quit Button implementation

    Smith.PowerOff {
        id: quitButton

        // Position the button over the graphics of the button on the
        // screen mask.
        height: 12; width: 12
        anchors.bottom: parent.bottom
        anchors.bottomMargin: 25
        anchors.horizontalCenter: parent.horizontalCenter
        // Set a z-depth for the object so it resides immediately under
        // the contextual help area (periodically shown in the same place).
        z: zQuit
        // Management of the clicked event:
        // stop all timers and quit the application.
        onClicked: {
            debugMessage("STOP TIMERS")
            waitCycle.running = false
            waitTwitter.running = false;
            bannerRotation.running = false;
            waitHelp.running = false;
            debugMessage("QUIT APPLICATION")
            Qt.quit();
        }
        focus:true
    }

}
